﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTO;

namespace BLL
{
    public class Evaluate
    {
        public double calculateDistance(int city1St, int city2St, CityObject[] cities)
        {
            return (Math.Sqrt((cities[city1St].X - cities[city2St].X) * (cities[city1St].X - cities[city2St].X) + (cities[city1St].Y - cities[city2St].Y) * (cities[city1St].Y - cities[city2St].Y)));
        }

        public double calCostOfTour(int[] tour, int numOfCity, CityObject[] citiesCoor)
        {
            double s = 0;
            for (int i = 0; i < numOfCity - 1; i++)
            {
                s = s + this.calculateDistance(tour[i] - 1, tour[i + 1] - 1, citiesCoor);
            }
                s = s + this.calculateDistance(tour[numOfCity - 1] - 1, tour[0] - 1, citiesCoor);
            return s;
        }

        //calculate cost of tour for real representation
        private int indexOfInt(int[] arr, int value)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == value)
                {
                    return i;
                }
            }
            return -1;
        }

        private int indexOfDouble(double[] arr, double value)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == value)
                {
                    return i;
                }
            }
            return -1;
        }

        //find index of arr array and don't selected
        private int indexOfDouble(double[] arr, double value, bool[] bitFlag)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if ((bitFlag[i]) && (arr[i] == value))
                {
                    return i;
                }
            }
            return -1;
        }


        #region path representation
            public double calCostOfTour(PathTour tour, int numOfCity, CityObject[] citiesCoor)
            {
                double s = 0;
                for (int i = 0; i < numOfCity - 1; i++)
                {
                    s = s + this.calculateDistance(tour.OrderCity[i] - 1, tour.OrderCity[i + 1] - 1, citiesCoor);                
                }
                s = s + this.calculateDistance(tour.OrderCity[numOfCity - 1] - 1, tour.OrderCity[0] - 1, citiesCoor);            
                return s;
            }

            public void calculateFitness(ref PathTour tour, ref PathTour bestTour, int numOfCity, CityObject[] citiesCoor)
            {
                double costOfTour = this.calCostOfTour(tour, numOfCity, citiesCoor);
                tour.Fitness = costOfTour;//maxCost - _costOfTour;
                if ((bestTour == null) || (costOfTour < bestTour.Fitness))
                {
                    bestTour = (PathTour)tour.Clone();
                }
            }

            public double totalFitnessPopulation(List<PathTour> pop, int popSize)
            {
                double totalFitness = 0.0f;
                for (int i = 0; i < popSize; i++)
                {                    
                    totalFitness += pop[i].Fitness;
                }
                return totalFitness;
            }

        #endregion


    }
}
